#ifndef __FRAGMENT_TRANSPORTLAYER_H__
#define __FRAGMENT_TRANSPORTLAYER_H__

#define TRANSPORTLAYER_VERSION "1.0.0"


#include "stdint.h"
#include "stdbool.h"

#include "Fragment_LinkLayer.h"

#define MAX_PKT_LEN                     (FRAME_PAYLOAD_LEN)
#define MAX_PKT_PAYLOAD_LEN             (MAX_PKT_LEN - 4) // -4 for packet_id, total_packets, current_index, payload_length 

#define MAX_TOTAL_LENGTH                (128)               // total payload length
#define MAX_TOTAL_LENGTH_CHECKSUM       (MAX_TOTAL_LENGTH + 2) // +2 for checksum
#define MAX_TOTAL_PACKETS               ((MAX_TOTAL_LENGTH + MAX_PKT_PAYLOAD_LEN - 1) / MAX_PKT_PAYLOAD_LEN)
#define BITMAP_SIZE                     ((MAX_TOTAL_PACKETS + 7) / 8)

#define BITMAP_SET(bitmap, i)           ((bitmap)[(i)/8] |= (1 << ((i)%8)))
#define BITMAP_GET(bitmap, i)           (((bitmap)[(i)/8] >> ((i)%8)) & 0x01)


typedef struct PacketBuff
{
    uint8_t arrData[MAX_PKT_LEN];
    uint16_t length;
} PacketBuff_t;



typedef enum
{
    ReassemblyResult_Successful = 0,
    ReassemblyResult_PacketIdMismatch,
    ReassemblyResult_NuLLPtr,
    ReassemblyResult_RepeatFrame,
    ReassemblyResult_Overflow,
    ReassemblyResult_ChecksumFail,
} Fragment_ReassemblyState_e;

typedef struct
{
    bool flag_complete;
    uint8_t packet_id;
    uint8_t total_packets;
    uint8_t received_count;
    uint8_t received_bitmap[BITMAP_SIZE];  // 位图节省空间
    uint8_t whole_payload[MAX_TOTAL_LENGTH_CHECKSUM]; // +2 for checksum
    uint16_t whole_length;
    uint16_t checksum;
} Fragment_ReassemblyContext_t;

typedef struct {
    const uint8_t* data;        // 原始数据指针
    uint16_t total_length;      // 原始数据总长度
    uint8_t packet_id;          // 包ID
    uint8_t total_packets;      // 总包数
    uint8_t current_index;      // 当前准备拆第几个包
    uint16_t checksum;
} Fragment_SplitContext_t;

typedef struct
{
    uint8_t packet_id;           // 一个完整数据的唯一标识
    uint8_t total_packets;       // 总包数
    uint8_t current_index;       // 当前是第几包（从0开始）
    uint8_t payload_length;      // 当前包负载长度
    uint8_t payload[MAX_PKT_LEN];// 实际数据
} Fragment_Packet_t;


typedef void (*TransferFunc_t)(const uint8_t* data, const uint16_t length);

uint16_t Fragment_Packet_Serialize(const Fragment_Packet_t* in_Pkt, uint8_t* output, uint16_t buf_size);
bool Fragment_Packet_Parse(const uint8_t* in_Buff, const uint16_t length, Fragment_Packet_t* out_Pkt);

bool Fragment_Packet_Split_Init(Fragment_SplitContext_t* ctx, const uint8_t* data, uint16_t length);
bool Fragment_Packet_Split(Fragment_SplitContext_t* ctx, Fragment_Packet_t* out_packet);

bool Fragment_Packet_Reassemble_Init(Fragment_ReassemblyContext_t* ctx);
Fragment_ReassemblyState_e Fragment_Packet_Reassemble(Fragment_ReassemblyContext_t* ctx, const Fragment_Packet_t* pkt);

void Fragment_TransportInit(TransferFunc_t send_callback, TransferFunc_t recv_callback);
void Fragment_Transmitter(const uint8_t* in_Buff, const uint16_t length);
void Fragment_Received(const uint8_t* in_Buff, const uint16_t length);
#endif // __FRAGMENT_TRANSPORTLAYER_H__